package com.cby.operation.anti

import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Build
import android.os.Bundle
import android.text.Html
import android.view.Gravity
import android.widget.ImageView
import android.widget.TextView
import com.cby.operation.anti.bean.AntiConfig
import com.cby.operation.anti.bean.LinkBean
import com.cby.operation.anti.bean.PopConfigBean
import com.cby.operation.anti.data.AntiAddictApiRepository
import com.cby.operation.anti.ui.AntiDialogFragment
import com.cby.operation.anti.ui.RealNameDialogFragment
import com.cby.operation.common.ext.dip2px
import com.cby.operation.common.ext.getId
import com.cby.operation.common.ext.getLayoutId
import com.cby.operation.common.ui.UIStackManager
import com.cby.operation.common.util.AppUtils
import com.cby.operation.common.util.CbyLogUtils
import com.cby.operation.common.util.HandlerUtils
import com.cby.operation.common.util.WebUtils
import com.cby.operation.common.widget.floatview.HykbFloatView
import com.cby.operation.common.widget.floatview.OnClickListener
import com.cby.operation.sdk.SdkConfiguration
import com.cby.operation.sdk.TAG_FRAGMENT_ANTI
import com.cby.operation.sdk.TAG_FRAGMENT_REAL_NAME
import org.json.JSONObject
import java.lang.ref.WeakReference
import java.util.*

/**
 * @description: AntiAddictManager
 *
 * @author ChenBaoyang
 * @date 8/2/21 09:52
 */
class AntiAddictManager : AntiHeartManager.HeartListener {

    private object SingletonHolder {
        /**
         * 返回InitManager对象
         */
        val instance = AntiAddictManager()
    }


    companion object{

        val instance = SingletonHolder.instance

        /**
         * 日志标识
         */
        private const val TAG = "AntiAddictManager"

        /**
         * 用户不需要进行防沉迷限制
         */
        private const val CODE_NOT_FCM = 100


        /**
         * 用户需要防沉迷限制，返回剩余游戏时长，允许游戏
         */
        private const val CODE_NEED_FCM_RETURN_TIME = 200

        /**
         * 用户需要防沉迷限制，提醒用户限制游戏倒计时，允许游戏；
         */
        private const val CODE_NEED_FCM_COUNT_TIME = 201

        /**
         * 用户游戏时长剩余不足10分钟，建议客户端开启倒计时
         */
        private const val CODE_FCM_START_COUNT_TIME = 202

        /**
         * 用户需要防沉迷限制，弹窗提醒用户相关信息，禁止游戏；
         */
        private const val CODE_BAN_GAME = 203

        /**
         * 参数错误
         */
        private const val CODE_PARAM_EXCEPTION = 401

        /**
         * 心跳token异常
         */
        private const val CODE_TOKEN_EXCEPTION = 402

        /**
         * 心跳服务器异常
         */
        private const val CODE_SERVER_EXCEPTION = 403

        /**
         * 返回的参数key
         */
        private const val KEY_CODE = "code"
        private const val KEY_MSG = "message"
        private const val KEY_DATA = "result"
    }

    private var config: AntiConfig

    private lateinit var activity: Activity
    private lateinit var gameId: String
    private lateinit var uid: String
    private lateinit var nick: String
    private lateinit var loginType: String
    private lateinit var userToken: String

    private var isFromBackGround: Boolean? = false

    private var mFloatView: HykbFloatView? = null

    private var listenerReference: WeakReference<AntiAddictListener>? = null

    init {
        //增加心跳接口的回调监听
        AntiHeartManager.instance.setHeartListener(this)
        config = AntiConfig()
    }

    /**
     * 开启检测防沉迷
     *
     * @param activity Activity
     * @param userId String
     * @param nick String
     * @param loginType String
     */
    fun startAnti(
        activity: Activity,
        userId: String,
        nick: String,
        loginType: String,
        token: String,
        listener: AntiAddictListener
    ) {

        kotlin.run {
            this.activity = activity
            this.gameId = SdkConfiguration.gameId
            this.uid = userId
            this.nick = nick
            this.loginType = loginType
            this.userToken = token
            this.listenerReference = WeakReference(listener)
        }

        HandlerUtils.runOnMainThread {
            checkAnti(0)
            registerActivityLifecycleCallbacks()
        }
    }

    private fun checkAnti(time: Long) {
        try {
            val token = config.token
            AntiAddictApiRepository.requestFcmData(gameId, uid, token, time)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 结束防沉迷
     */
    fun stopAnti() {
        //清空token
        config.resetToken()
        //停止心跳
        AntiHeartManager.instance.stopHeart()
        //注销全局监听
        unregisterActivityLifecycleCallbacks()
    }

    override fun onBeat(time: Long) {
        checkAnti(time)
    }

    override fun onCountDown(bean: PopConfigBean?) {
        if (bean!!.type == 2) {
            showFcmFloat(bean.content, bean.linkBean)
        } else {
            val beans: MutableList<PopConfigBean> = ArrayList()
            beans.add(bean)
            showFcmPop(beans)
        }
    }

    @Throws(java.lang.Exception::class)
    fun parseResponse(response: String?) {
        parseFcmData(response!!)
    }

    /**
     * 解析防沉迷数据
     *
     * @throws Exception
     */
    @Throws(java.lang.Exception::class)
    private fun parseFcmData(response: String) {
        val data = JSONObject(response)
        val code = data.optInt(KEY_CODE)
        val msg = data.optString(KEY_MSG)
        val dataJson = data.optJSONObject(KEY_DATA)
        config.parseData(dataJson)
        when (code) {
            CODE_NOT_FCM -> {
                // 不做防沉迷，正常游戏
                AntiHeartManager.instance.stopHeart()
                unregisterActivityLifecycleCallbacks()
                dismissAntiDialog()
                dismissRealNameDialog()
            }
            CODE_NEED_FCM_RETURN_TIME -> {
                // 做防沉迷心跳，返回剩余游戏时长
                AntiHeartManager.instance
                    .setRemainingTime(config.remainingTime, config.getCountDownBeans())
                AntiHeartManager.instance.startHeart(config.interval)
                dismissAntiDialog()
                dismissRealNameDialog()
            }
            CODE_NEED_FCM_COUNT_TIME -> {
                // 做防沉迷心跳，开始倒计时
                AntiHeartManager.instance
                    .setRemainingTime(config.remainingTime, config.getCountDownBeans())
                AntiHeartManager.instance.startHeart(config.interval)
                config.getPopConfigs()?.let { showFcmPop(it) }
            }
            CODE_FCM_START_COUNT_TIME -> {
                // 客户端做倒计时操作
                AntiHeartManager.instance
                    .setRemainingTime(config.remainingTime, config.getCountDownBeans())
                AntiHeartManager.instance.startHeart(config.interval)
                //做个判断是不是需要弹夜间的倒计时的弹窗
                if (config.getPopConfigs()!!.isEmpty() && config.getCountDownBeans()!!.isEmpty()
                ) {
                    val beans: MutableList<PopConfigBean> = ArrayList()
                    beans.add(config.offLineBean!!)
                    showFcmPop(beans)
                } else if (config.getPopConfigs()!!.isEmpty()) {
                    dismissAntiDialog()
                    dismissRealNameDialog()
                } else {
                    config.getPopConfigs()?.let { showFcmPop(it) }
                }
            }
            CODE_BAN_GAME -> {
                //禁止游戏
                config.getPopConfigs()?.let {
                    showFcmPop(it)
                }

                AntiHeartManager.instance.stopHeart()
                unregisterActivityLifecycleCallbacks()
            }
            CODE_PARAM_EXCEPTION ->
                // 参数异常
                CbyLogUtils.e(TAG, msg)
            CODE_TOKEN_EXCEPTION ->
                // token异常
                CbyLogUtils.e(TAG, msg)
            CODE_SERVER_EXCEPTION ->
                // 服务端异常
                CbyLogUtils.e(TAG, msg)
            else -> {
            }
        }
    }

    /**
     * 防沉迷UI显示
     */
    private fun showFcmPop(beans: List<PopConfigBean>) {
        CbyLogUtils.i("m3839", "beans.size = " + beans.size)
        if (beans.size == 1) {
            val bean = beans[0]
            HandlerUtils.runOnMainThread {
                if (bean.type == 1) {
                    //表示弹窗
                    openFcmDialog(beans)
                } else if (bean.type == 2) {
                    //表示气泡
                    showFcmFloat(bean.content, bean.linkBean)
                    dismissAntiDialog()
                }
            }
        } else if (beans.size == 2 && (beans[0].type == 1 || beans[1].type == 1)) {
            HandlerUtils.runOnMainThread { openFcmDialog(beans) }
        }
    }

    /**
     * 显示悬浮窗体
     */
    fun showFcmFloat(tip: String?, linkBean: LinkBean?) {
        if (mFloatView != null) {
            mFloatView!!.setText(activity.getId("tv_tip"), Html.fromHtml(tip))
            mFloatView!!.setText(activity.getId("tv_detail"), linkBean!!.name)
            mFloatView!!.show()
            return
        }

        mFloatView = HykbFloatView(activity)
            .setDuration(3000)
            .setView(activity.getLayoutId("anti_float_pop"))
            .setGravity(Gravity.TOP or Gravity.START)
            .setYOffset(activity.dip2px(8F))
            .setText(activity.getId("tv_tip"), Html.fromHtml(tip))
            .setText(activity.getId("tv_detail"), linkBean!!.name)
            .setOnClickListener(activity.getId("iv_close"),
                object : OnClickListener<ImageView> {
                    override fun onClick(floatView: HykbFloatView, view: ImageView) {
                        mFloatView!!.cancel()
                        mFloatView = null
                    }
                })
            .setOnClickListener(activity.getId("tv_detail"),
                object : OnClickListener<TextView> {
                    override fun onClick(floatView: HykbFloatView, view: TextView) {
                        linkBean.url?.let { WebUtils.openUrl(activity, it) }
                    }
                })
            .show()
    }

    /**
     * 开启对话框
     */
    private fun openFcmDialog(beans: List<PopConfigBean>) {

        mFloatView?.let {
            it.cancel()
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (activity.isFinishing || activity.isDestroyed) {
                return
            }
        } else {
            if (activity.isFinishing) {
                return
            }
        }
        if (UIStackManager.instance!!.hasFragment(TAG_FRAGMENT_ANTI)) {
            val fragment : AntiDialogFragment =
                UIStackManager.instance!!.getFragment(TAG_FRAGMENT_ANTI) as AntiDialogFragment
            fragment.update(beans, nick, uid, loginType)
            return
        }
        AntiDialogFragment.show(activity, beans, nick, uid, loginType)

    }

    /**
     * 打开实名认证的web
     *
     * @param activity Activity
     */
    fun openRealNameWeb(activity: Activity) {
        RealNameDialogFragment.show(
            activity,
            uid,
            loginType,
            userToken
        )
    }


    /**
     * 隐藏防沉迷弹窗
     */
    private fun dismissAntiDialog() {
        UIStackManager.instance!!.finishFragment(TAG_FRAGMENT_ANTI)
    }

    /**
     * 隐藏实名认证弹窗
     */
    private fun dismissRealNameDialog() {
        UIStackManager.instance!!.finishFragment(TAG_FRAGMENT_REAL_NAME)
    }

    /**
     * 注册全局activity生命周期的监听
     */
    private fun registerActivityLifecycleCallbacks() {
        activity.application.registerActivityLifecycleCallbacks(lifecycleCallbacks)
    }

    /**
     * 注销全局activity的生命周期
     */
    private fun unregisterActivityLifecycleCallbacks() {
        activity.application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks)
    }

    private val lifecycleCallbacks: ActivityLifecycleCallbacks =
        object : ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
            override fun onActivityStarted(activity: Activity) {
                if (isFromBackGround == true) {
                    AntiHeartManager.instance.setPause(false)
                    isFromBackGround = false
                }
            }

            override fun onActivityResumed(activity: Activity) {
                if (instance.activity == activity) {
                    return
                }
                instance.activity = activity
            }

            override fun onActivityPaused(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {
                if (AppUtils.isAppIsInBackground(activity)) {
                    isFromBackGround = true
                    AntiHeartManager.instance.setPause(true)
                }
            }

            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {}
        }

    /**
     * 处理对外回调
     *
     * @param code Int
     * @param message String
     */
    fun handleEventBack(code: Int, message: String) {
        listenerReference?.let { it.get()?.onEventBack(code, message) }
    }
}